home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 4 / The Arsenal Files 4 (Arsenal Computer).ISO / casm / au116-as.exe / SCAN.CPP < prev    next >
C/C++ Source or Header  |  1994-12-13  |  10KB  |  371 lines

  1. // ASCAN.CPP                                 1          1    6666
  2. // Dave Harris                                11         11   6
  3. // Compiled using Borland C++ ver 3.1       1 1        1 1   6666
  4. // 03-03-94                                  1     ..   1   6   6
  5. //                                           11111 .. 11111  666
  6. ////////////////////////////////////////////////////////////////////////
  7.  
  8. #include "au.hpp"
  9.  
  10. #define PROGRAM "SCAN"   // Name of module
  11. /*********************************************************************/
  12.  
  13. typedef struct
  14. {
  15.     char rename_virus[FILE_SIZE];     // What to rename it to
  16.     char archives;                     // do inside arcs period
  17.     int  newer_than;
  18.     long random_num;
  19.     int  scan_version;
  20.     char recurse;
  21. } SCAN_INFO;
  22.  
  23. static int scan_process(AU *, char *, char *, char *, ARC_HANDLE *);
  24.  
  25. /*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
  26. static int is_newer(AU *au, char *file_name)
  27. {
  28.     HANDLE handle(0);
  29.     struct ftime ftime_hold;
  30.     long value;
  31.     SCAN_INFO *in = (SCAN_INFO *)au->info;
  32.  
  33.     handle.open(au, file_name);
  34.     handle.get_time(&ftime_hold);
  35.     handle.close();
  36.  
  37.     if (in->scan_version == 0 || in->newer_than == 0)
  38.         return TRUE;
  39.  
  40.     value = (long)ftime_hold.ft_hour*60*30+ftime_hold.ft_min*30+
  41.             ftime_hold.ft_tsec;
  42.     value -= in->scan_version + in->random_num;
  43.     if (value < 0)
  44.         value = -value;
  45.  
  46.     if (value < in->newer_than)
  47.         return FALSE;
  48.     else
  49.         return TRUE;
  50. }
  51. /*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
  52. int scan_one_file(AU *au, char *file_name)
  53. {
  54.     char string2[CLENGTH];
  55.  
  56.     sprintf(string2, "%s %s", au->scanner, file_name);
  57.     return execute(au, string2, au->output, NULL, au->scannerMemNeeded);
  58. }
  59. /*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
  60. static int recurse(AU *au, char *path)
  61. {
  62.     struct       ffblk ffblk;           // directory entry structure
  63.     LISTPTR    file_list;
  64.     LIST      *el;
  65.     int        retCode = FALSE;
  66.     char       holdCurDir[FLENGTH];
  67.     char       curDir[FLENGTH];
  68.     char       destDir[FLENGTH];
  69.     ARC_HANDLE arc_handle;
  70.  
  71.     cd(au, path, holdCurDir);
  72.     getcwd(curDir, FLENGTH);
  73.     build_fname(destDir, curDir, TEMP_DIR);
  74.     mkdir(TEMP_DIR);
  75.  
  76.     if (!findfirst("*.*", &ffblk, 0))
  77.     {
  78.         do
  79.         {
  80.             file_list.add(ffblk.ff_name);
  81.         }  while (!findnext(&ffblk));
  82.     }
  83.  
  84.     for (el = file_list.head; el != NULL; el = el->next)
  85.     {
  86.         arc_handle.init(au, el->data);
  87.         arc_handle.deinit(au);
  88.         if (arc_handle.type > 0)
  89.         {
  90.             if (scan_process(au, path, destDir, el->data, &arc_handle) != 0)
  91.                 retCode = TRUE;
  92.         }
  93.     }
  94.     file_list.destroy();
  95.     cd(au, curDir, NULL);
  96.     rmdir(TEMP_DIR);
  97.     cd(au, holdCurDir, NULL);
  98.     return retCode;
  99. }
  100. /*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
  101. static int scan_process(AU *au, char *sourceDir, char *destDir, char *file_name,
  102.                         ARC_HANDLE *arc_handle)
  103. {
  104.     HANDLE     handle;
  105.     int      virus_found;
  106.     int      ret_code;
  107.     char    *char_ptr;
  108.     LISTPTR  paths;
  109.     LIST    *el;
  110.     SCAN_INFO *in = (SCAN_INFO *)au->info;
  111.  
  112.     if (in->archives == ON)       /* Test self extracts itself for viruses */
  113.     {                              /* and gets regular files too */
  114.         if (arc_handle->type > 0)
  115.             goto noscan;
  116.     }
  117.  
  118. /* self extract or individual file **************************/
  119.  
  120.     ret_code = scan_one_file(au, file_name);
  121.  
  122.     if (ret_code == au->SC_Virus_EL || (au->SC_Virus_EL == -1 && ret_code > 0))
  123.     {
  124.         if (in->rename_virus[0] != '\0')
  125.         {
  126.             rename(file_name, fit_mask(file_name, in->rename_virus));
  127.             fix_flist(au, file_name, fit_mask(file_name, in->rename_virus));
  128.         }
  129.         add_to_bad_list(au, sourceDir, file_name, ret_code, 2);
  130.         if (arc_handle->is_self)  // now lets not go and unarc (execute) it
  131.             return TRUE;
  132.     }
  133.     else if (ret_code != au->SC_NoVirus_EL || (au->SC_NoVirus_EL == -1 && ret_code != 0))
  134.         add_to_bad_list(au, sourceDir, file_name, ret_code, 4);
  135. /**************************************/
  136.  noscan:
  137.  
  138.     if (in->archives==OFF || !(arc_handle->type > 0 || arc_handle->is_self) )
  139.         goto around;
  140.  
  141.     unarc(au, file_name, destDir, &paths, 0, FALSE);
  142.  
  143.     paths.add(destDir);
  144.  
  145.     virus_found = FALSE;
  146.     for (el = paths.head; el != NULL; el = el->next)
  147.     {
  148.         if (in->recurse == ON)
  149.         {
  150.             if (recurse(au, el->data) != 0)
  151.                 virus_found = TRUE;
  152.         }
  153.         ret_code = scan_one_file(au, el->data);
  154.         if (ret_code == au->SC_Virus_EL || (au->SC_Virus_EL == -1 && ret_code > 0))
  155.         {
  156.             virus_found = TRUE;
  157.             if (in->rename_virus[0] != '\0')
  158.             {
  159.                 rename(file_name, fit_mask(file_name, in->rename_virus));
  160.                 fix_flist(au, file_name, fit_mask(file_name, in->rename_virus));
  161.             }
  162.             add_to_bad_list(au, sourceDir, file_name, ret_code, 2);
  163.             break;
  164.         }
  165.         else if (ret_code != au->SC_NoVirus_EL || (au->SC_NoVirus_EL == -1 && ret_code != 0))
  166.             add_to_bad_list(au, sourceDir, file_name, ret_code, 4);
  167.     }
  168.     clean_paths(au, &paths);
  169.  
  170.     if (virus_found)
  171.         return TRUE;
  172.  
  173.  around:
  174.     if (in->scan_version!=0)
  175.     {
  176.         struct ftime ftime_hold;
  177.         long value = in->random_num + in->scan_version;
  178.  
  179.         handle.open(au, file_name);
  180.         handle.get_time(&ftime_hold);
  181.         ftime_hold.ft_tsec = 0;
  182.         ftime_hold.ft_hour = value / (60*30);
  183.         value-= ftime_hold.ft_hour*(60*30);
  184.         ftime_hold.ft_min = value / 30;
  185.         value-= ftime_hold.ft_min*(30);
  186.         ftime_hold.ft_tsec = value;
  187.         handle.set_time(&ftime_hold);
  188.         handle.close();
  189.     }
  190.     return FALSE;
  191. }
  192. /*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
  193. static int scan(AU *au, char *file_name)
  194. {
  195.     ARC_HANDLE arc_handle;
  196.  
  197.     check_for_key();
  198.  
  199.     if (!is_newer(au, file_name))
  200.         return 0;
  201.  
  202.     if (!au->no_extra)
  203.         au_printf(au, "@?6Scanning @?1%s@?H\n", file_name);
  204.     act_log_printf(au, "   + SCAN    : %s", file_name);
  205.  
  206.     au->number_processed++;
  207.  
  208.     arc_handle.init(au, file_name);
  209.     arc_handle.deinit(au);
  210.  
  211.     scan_process(au, au->source_directory, au->dest_directory, file_name,
  212.                  &arc_handle);
  213.     return 0;
  214. }
  215. /*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
  216. static void ReadCFGInfo(AU *au, CFG_HANDLE *cfg_handle)
  217. {
  218.     char string[200],
  219.          string2[200],
  220.          string3[200];
  221.     SCAN_INFO *in = (SCAN_INFO *)au->info;
  222.  
  223.     for(EVER)
  224.     {
  225.         if (cfg_handle->read_line(au, string)==EOF)
  226.             break;
  227.  
  228.         split_string(string, string2);
  229.         split_string(string, string3);
  230.  
  231.         if (string2[0] == '\0')
  232.             continue;
  233.  
  234.         strcpy(au->curOpt, string2);
  235.         au->curVal = string3;
  236.         switch (toupper(string2[1]) << 8 | toupper(string2[0]))
  237.         {
  238.             case 'BE':                                          // Begin
  239.                 return;
  240.             case 'SE':                                          // Self_Extracts
  241.                 au->self_extracts = get_value(au, OFF | ON);
  242.                 break;
  243.             case 'RE':                                          // Recurse
  244.                 in->recurse = get_value(au, OFF | ON);
  245.                 break;
  246.             case 'VE':                                          // Version
  247.                 in->scan_version = atoi(string3);
  248.                 break;
  249.             case 'NE':                                          // Newer_than
  250.                 in->newer_than = atoi(string3);
  251.                 break;
  252.             case 'RA':
  253.                 in->random_num = atoi(string3);
  254.                 break;
  255.             case 'VI':
  256.                 strcpy(in->rename_virus, string3);
  257.                 break;
  258.             case 'PA':
  259.                 au->pause = get_value(au, OFF | ON);
  260.                 break;
  261.             default:
  262.                 cfg_handle->invalid_option(au, string2);
  263.         }
  264.     }
  265. }
  266. /*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
  267. static BYTE parse_comm_line(AU *au, char option, char *cur_argv,
  268.                             PARSE_TYPE type)
  269. {
  270.     SCAN_INFO *in = (SCAN_INFO *)au->info;
  271.  
  272.     switch (type)
  273.     {
  274.     case PARSE_PARAM_OPTION:
  275.         switch (option)
  276.         {
  277.         case 'X':
  278.             au->self_extracts = get_value(au, OFF | ON);
  279.             break;
  280.         case 'A':
  281.             in->archives = get_value(au, OFF | ON);
  282.             break;
  283.         case 'R':
  284.             in->recurse = get_value(au, OFF | ON);
  285.             break;
  286.         case 'N':
  287.             in->newer_than = atoi(cur_argv);
  288.             break;
  289.         case 'V':
  290.             in->scan_version = atoi(cur_argv);
  291.             break;
  292.         case 'W':
  293.             strcpy(au->dest_directory, cur_argv);
  294.             break;
  295.         case 'P':
  296.             au->pause = get_value(au, OFF | ON);
  297.             break;
  298.         case '?':
  299.             au_standard_opt_header(au, "SCan",
  300.                "@?3-X@?Hon|off     self eXtracts\n"
  301.                "@?3-A@?Hon|off     look inside Archives\n"
  302.                "@?3-R@?Hon|off     Recurse\n"
  303.                "@?3-V@?Hn          n=Version of scanner being used\n"
  304.                "                use 0 to leave time stamp unchanged\n"
  305.                "@?3-N@?Hn          scan only if scanned more than n versions ago\n"
  306.                "@?3-P@?Hon|off     Pause after bad archive found\n"
  307.                "@?3-W@?H<dir>      Work directory\n");
  308.             exit (0);
  309.         default:
  310.              au_invalid_option(au, PROGRAM, option);
  311.         }               /* end switch */
  312.         return TRUE;
  313.     case PARSE_POST_CHECK:
  314.         if (in->random_num == 0)
  315.         {
  316.             au_printf_error(au, "Need a non-zero random number in the .cfg file");
  317.             exit(1);
  318.         }
  319.         if (in->newer_than > 10)
  320.         {
  321.             au_printf_error(au, "Newer_Than is larger than recommended!!!!!");
  322.             if (!ask_continue())
  323.                 exit(1);
  324.         }
  325.         if (au->scanner[0] == '\0')
  326.         {
  327.             au_printf_error(au, "No scanner specified\n");
  328.             exit(1);
  329.         }
  330.  
  331.         return TRUE;
  332.     }
  333.     return FALSE;
  334. }
  335. /*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
  336. int main_scan(AU *au, int argc, char *argv[])
  337. {
  338.     SCAN_INFO *in;
  339.  
  340.     in = new SCAN_INFO;
  341.     memset(in, '\0', sizeof(SCAN_INFO));
  342.     au->info = in;
  343.     in->archives=ON;
  344.  
  345.     ReadGlobalCFGInfo(au, au->cfg_file, PROGRAM, ReadCFGInfo);
  346.     generic_parse_comm_line(au, argc, argv, parse_comm_line);
  347.  
  348.     if (au->dest_directory[0] != '\0')
  349.     {
  350.         /* make sure it exists */
  351.         cd(au, au->dest_directory, au->old_dest_dir);
  352.         getcwd(au->dest_directory, FLENGTH);
  353.         cd(au, au->cur_directory);
  354.     }
  355.     else
  356.         build_fname(au->dest_directory, au->cur_directory, TEMP_DIR);
  357.  
  358.     au->unarc_paths = ON;
  359.     au->recurse = OFF;         // uses a different style of recurse
  360.  
  361.     mkdir(TEMP_DIR);
  362.     process_files(au, scan);
  363.     rmdir(TEMP_DIR);
  364.  
  365.     if (!au->no_extra)
  366.         au_printf_c(au, 15, "\nFiles Scanned = %d\n\n", au->number_processed);
  367.  
  368.     return 0;
  369. }
  370.  
  371.